home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_10 / phillips / cntlwarp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-18  |  10.3 KB  |  425 lines

  1.  
  2. #include "cips.h"
  3.  
  4. #define FILL 150
  5.  
  6.  
  7.      /*******************************************
  8.      *
  9.      *   warp(..
  10.      *
  11.      *   This routine warps a ROWSxCOLS section
  12.      *   of an image.  The il, ie parameters
  13.      *   specify which ROWSxCOLS section of
  14.      *   the image to warp.  The x_control and
  15.      *   y_control parameters are the control
  16.      *   points inside that section.  Therefore,
  17.      *   x_control and y_control will always be
  18.      *   less the COLS and ROWS.
  19.      *
  20.      *   The point coordinates are for the four
  21.      *   corners of a four side figure.
  22.      *      x1,y1     x2,y2
  23.      *
  24.      *      x4,y4     x3,y3
  25.      *
  26.      *******************************************/
  27.  
  28. warp(in_name, out_name, the_image, out_image,
  29.      il, ie, ll, le, x_control, y_control,
  30.      bilinear)
  31.    char   in_name[], out_name[];
  32.    int    bilinear, il, ie, ll, le, 
  33.           x_control, y_control;
  34.    short  the_image[ROWS][COLS],
  35.           out_image[ROWS][COLS];
  36. {
  37.    int    cols_div_2, extra_x, extra_y, i, j,
  38.           rows_div_2, x1, x2, x3, x4, y1, y2, y3, y4;
  39.  
  40.    struct tiff_header_struct image_header;
  41.  
  42.    create_file_if_needed(in_name, out_name, out_image);
  43.  
  44.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  45.  
  46.    cols_div_2 = COLS/2;
  47.    rows_div_2 = ROWS/2;
  48.  
  49.       /***********************************
  50.       *
  51.       *   1 - upper left quarter
  52.       *
  53.       ***********************************/
  54.  
  55.    x1 = 0;
  56.    x2 = cols_div_2;
  57.    x3 = x_control;
  58.    x4 = 0;
  59.  
  60.    y1 = 0;
  61.    y2 = 0;
  62.    y3 = y_control;
  63.    y4 = rows_div_2;
  64.  
  65.    extra_x = 0;
  66.    extra_y = 0;
  67.  
  68.    if(bilinear)
  69.       bi_warp_loop(the_image, out_image,
  70.                    x1, x2, x3, x4,
  71.                    y1, y2, y3, y4,
  72.                    extra_x, extra_y);
  73.    else
  74.       warp_loop(the_image, out_image,
  75.                 x1, x2, x3, x4,
  76.                 y1, y2, y3, y4,
  77.                 extra_x, extra_y);
  78.  
  79.       /***********************************
  80.       *
  81.       *   2 - upper right quarter
  82.       *
  83.       ***********************************/
  84.  
  85.    x1 = cols_div_2;
  86.    x2 = COLS-1;
  87.    x3 = COLS-1;
  88.    x4 = x_control;
  89.  
  90.    y1 = 0;
  91.    y2 = 0;
  92.    y3 = rows_div_2;
  93.    y4 = y_control;
  94.  
  95.    extra_x = cols_div_2;
  96.    extra_y = 0;
  97.  
  98.  
  99.    if(bilinear)
  100.       bi_warp_loop(the_image, out_image,
  101.                    x1, x2, x3, x4,
  102.                    y1, y2, y3, y4,
  103.                    extra_x, extra_y);
  104.    else
  105.       warp_loop(the_image, out_image,
  106.                 x1, x2, x3, x4,
  107.                 y1, y2, y3, y4,
  108.                 extra_x, extra_y);
  109.  
  110.       /***********************************
  111.       *
  112.       *   3 - lower right quarter
  113.       *
  114.       ***********************************/
  115.  
  116.    x1 = x_control;
  117.    x2 = COLS-1;
  118.    x3 = COLS-1;
  119.    x4 = cols_div_2;
  120.  
  121.    y1 = y_control;
  122.    y2 = rows_div_2;
  123.    y3 = ROWS-1;
  124.    y4 = ROWS-1;
  125.  
  126.    extra_x = cols_div_2;
  127.    extra_y = rows_div_2;
  128.  
  129.    if(bilinear)
  130.       bi_warp_loop(the_image, out_image,
  131.                    x1, x2, x3, x4,
  132.                    y1, y2, y3, y4,
  133.                    extra_x, extra_y);
  134.    else
  135.       warp_loop(the_image, out_image,
  136.                 x1, x2, x3, x4,
  137.                 y1, y2, y3, y4,
  138.                 extra_x, extra_y);
  139.  
  140.       /***********************************
  141.       *
  142.       *   4 - lower left quarter
  143.       *
  144.       ***********************************/
  145.  
  146.    x1 = 0;
  147.    x2 = x_control;
  148.    x3 = cols_div_2;
  149.    x4 = 0;
  150.  
  151.    y1 = rows_div_2;
  152.    y2 = y_control;
  153.    y3 = ROWS-1;
  154.    y4 = ROWS-1;
  155.  
  156.    extra_x = 0;
  157.    extra_y = rows_div_2;
  158.  
  159.    if(bilinear)
  160.       bi_warp_loop(the_image, out_image,
  161.                    x1, x2, x3, x4,
  162.                    y1, y2, y3, y4,
  163.                    extra_x, extra_y);
  164.    else
  165.       warp_loop(the_image, out_image,
  166.                 x1, x2, x3, x4,
  167.                 y1, y2, y3, y4,
  168.                 extra_x, extra_y);
  169.  
  170.    write_array_into_tiff_image(out_name, out_image,
  171.                                il, ie, ll, le);
  172. }  /* ends warp */
  173.  
  174.  
  175.  
  176.  
  177.  
  178.      /*******************************************
  179.      *
  180.      *   warp_loop(..
  181.      *
  182.      *   This routine sets up the coefficients
  183.      *   and loops through a quarter of the
  184.      *   ROWSxCOLS section of the image that
  185.      *   is being warped.
  186.      *
  187.      *******************************************/
  188.  
  189. warp_loop(the_image, out_image,
  190.           x1, x2, x3, x4,
  191.           y1, y2, y3, y4,
  192.           extra_x, extra_y)
  193.    int    extra_x, extra_y,
  194.           x1, x2, x3, x4,
  195.           y1, y2, y3, y4;
  196.    short  the_image[ROWS][COLS],
  197.           out_image[ROWS][COLS];
  198. {
  199.    int    cols_div_2, denom, i, j, rows_div_2,
  200.           xa, xb, xab, x_out, ya, yb, yab, y_out;
  201.  
  202.    cols_div_2 = COLS/2;
  203.    rows_div_2 = ROWS/2;
  204.    denom      = cols_div_2 * rows_div_2;
  205.  
  206.       /***********************************
  207.      *
  208.      *   Set up the terms for the
  209.      *   spatial transformation.
  210.      *
  211.      ***********************************/
  212.  
  213.    xa  = x2 - x1;
  214.    xb  = x4 - x1;
  215.    xab = x1 - x2 + x3 - x4;
  216.  
  217.    ya  = y2 - y1;
  218.    yb  = y4 - y1;
  219.    yab = y1 - y2 + y3 - y4;
  220.  
  221.       /***********************************
  222.      *
  223.      *   Loop through a quadrant and
  224.      *   perform the spatial
  225.      *   transformation.
  226.      *
  227.      ***********************************/
  228.  
  229.       /* NOTE a=j b=i */
  230.  
  231.    printf("\n");
  232.    for(i=0; i<rows_div_2; i++){
  233.       if( (i%10) == 0) printf("%d ", i);
  234.       for(j=0; j<cols_div_2; j++){
  235.  
  236.          x_out = x1 + (xa*j)/cols_div_2 +
  237.                (xb*i)/rows_div_2 + (xab*i*j)/(denom);
  238.          y_out = y1 + (ya*j)/cols_div_2 +
  239.                (yb*i)/rows_div_2 + (yab*i*j)/(denom);
  240.  
  241.          if(x_out < 0       ||
  242.             x_out >= COLS   ||
  243.             y_out < 0       ||
  244.             y_out >= ROWS)
  245.             out_image[i+extra_y][j+extra_x] = FILL;
  246.          else
  247.             out_image[i+extra_y][j+extra_x] =
  248.              the_image[y_out][x_out];
  249.  
  250.       }  /* ends loop over j */
  251.    }  /* ends loop over i */
  252.  
  253. }   /* ends warp_loop */
  254.  
  255.  
  256.  
  257.  
  258.  
  259.      /*******************************************
  260.      *
  261.      *   bi_warp_loop(..
  262.      *
  263.      *   This routine sets up the coefficients
  264.      *   and loops through a quarter of the
  265.      *   ROWSxCOLS section of the image that
  266.      *   is being warped.
  267.      *
  268.      *   This version of the routine uses bilinear
  269.      *   interpolation to find the gray shades.
  270.      *   It is more accurate than warp_loop,
  271.      *   but takes longer because of the floating
  272.      *   point calculations.
  273.      *
  274.      *******************************************/
  275.  
  276. bi_warp_loop(the_image, out_image,
  277.              x1, x2, x3, x4,
  278.              y1, y2, y3, y4,
  279.              extra_x, extra_y)
  280.    int    extra_x, extra_y,
  281.           x1, x2, x3, x4,
  282.           y1, y2, y3, y4;
  283.    short  the_image[ROWS][COLS],
  284.           out_image[ROWS][COLS];
  285. {
  286.    double cols_div_2, denom, di, dj, rows_div_2,
  287.           xa, xb, xab, x_out, ya, yb, yab, y_out;
  288.    int    i, j;
  289.  
  290.    cols_div_2 = (double)(COLS)/2.0;
  291.    rows_div_2 = (double)(ROWS)/2.0;
  292.    denom      = cols_div_2 * rows_div_2;
  293.  
  294.      /***********************************
  295.      *
  296.      *   Set up the terms for the
  297.      *   spatial transformation.
  298.      *
  299.      ***********************************/
  300.  
  301.    xa  = x2 - x1;
  302.    xb  = x4 - x1;
  303.    xab = x1 - x2 + x3 - x4;
  304.  
  305.    ya  = y2 - y1;
  306.    yb  = y4 - y1;
  307.    yab = y1 - y2 + y3 - y4;
  308.  
  309.      /***********************************
  310.      *
  311.      *   Loop through a quadrant and
  312.      *   perform the spatial
  313.      *   transformation.
  314.      *
  315.      ***********************************/
  316.  
  317.       /* NOTE a=j b=i */
  318.  
  319.    printf("\n");
  320.    for(i=0; i<rows_div_2; i++){
  321.       if( (i%10) == 0) printf("%d ", i);
  322.       for(j=0; j<cols_div_2; j++){
  323.  
  324.        di = (double)(i);
  325.        dj = (double)(j);
  326.  
  327.          x_out = x1 +
  328.                  (xa*dj)/cols_div_2 +
  329.                  (xb*di)/rows_div_2 +
  330.                  (xab*di*dj)/(denom);
  331.          y_out = y1 +
  332.                  (ya*dj)/cols_div_2 +
  333.                  (yb*di)/rows_div_2 +
  334.                  (yab*di*dj)/(denom);
  335.  
  336.          out_image[i+extra_y][j+extra_x] =
  337.           bilinear_interpolate(the_image, x_out, y_out);
  338.  
  339.       }  /* ends loop over j */
  340.    }  /* ends loop over i */
  341.  
  342. }   /* ends bi_warp_loop */
  343.  
  344.          .
  345.          .
  346.          .
  347.          .
  348.  
  349.      /*******************************************
  350.      *
  351.      *   bilinear_interpolate(..
  352.      *
  353.      *   This routine performs bi-linear
  354.      *   interpolation.
  355.      *
  356.      *   If x or y is out of range, i.e. less
  357.      *   than zero or greater than ROWS or COLS,
  358.      *   this routine returns a zero.
  359.      *
  360.      *   If x and y are both in range, this
  361.      *   routine interpolates in the horizontal
  362.      *   and vertical directions and returns
  363.      *   the proper gray level.
  364.      *
  365.      *******************************************/
  366.  
  367. bilinear_interpolate(the_image, x, y)
  368.    double x, y;
  369.    short  the_image[ROWS][COLS];
  370. {
  371.    double fraction_x, fraction_y,
  372.           one_minus_x, one_minus_y,
  373.           tmp_double;
  374.    int    ceil_x, ceil_y, floor_x, floor_y;
  375.    short  p1, p2, p3, result = FILL;
  376.  
  377.       /******************************
  378.       *
  379.       *   If x or y is out of range,
  380.       *   return a FILL.
  381.       *
  382.       *******************************/
  383.  
  384.    if(x < 0.0               ||
  385.       x >= (double)(COLS)   ||
  386.       y < 0.0               ||
  387.       y >= (double)(ROWS))
  388.       return(result);
  389.  
  390.    tmp_double = floor(x);
  391.    floor_x    = tmp_double;
  392.    tmp_double = floor(y);
  393.    floor_y    = tmp_double;
  394.    tmp_double = ceil(x);
  395.    ceil_x     = tmp_double;
  396.    tmp_double = ceil(y);
  397.    ceil_y     = tmp_double;
  398.  
  399.    fraction_x = x - floor(x);
  400.    fraction_y = y - floor(y);
  401.  
  402.    one_minus_x = 1.0 - fraction_x;
  403.    one_minus_y = 1.0 - fraction_y;
  404.  
  405.    tmp_double = one_minus_x * 
  406.                 (double)(the_image[floor_y][floor_x]) +
  407.                 fraction_x * 
  408.                 (double)(the_image[floor_y][ceil_x]);
  409.    p1         = tmp_double;
  410.  
  411.    tmp_double = one_minus_x * 
  412.                 (double)(the_image[ceil_y][floor_x]) +
  413.                 fraction_x * 
  414.                 (double)(the_image[ceil_y][ceil_x]);
  415.    p2         = tmp_double;
  416.  
  417.    tmp_double = one_minus_y * (double)(p1) +
  418.                 fraction_y * (double)(p2);
  419.    p3         = tmp_double;
  420.  
  421.  
  422.    return(p3);
  423.  
  424. }  /* ends bilinear_interpolate */
  425.